﻿/* 2011/11/12 */
using System;
using System.Drawing;

namespace Cosmos.Windows.Themes
{
    public class ExtendCountTheme : DynamicCountTheme
    {
        public ExtendCountTheme(ThemeSettings themeSettings)
            : base(themeSettings, 40, 40)
        {

        }

        protected override void PaintThemeImage(DynamicImageParameter presentParameter, DynamicImageParameter pastParameter)
        {
            PaintExtendImageByCount(presentParameter, pastParameter);
        }

        private void PaintExtendImageByCount(DynamicImageParameter presentParameter, DynamicImageParameter pastParameter)
        {
            Bitmap presentBitmap = presentParameter.Bitmap;
            string presentName = presentParameter.Name;
            string presentGroup = presentParameter.Group;
            int presentStartX = presentParameter.StartX;
            int presentStartY = presentParameter.StartY;
            int presentDisplayWidth = presentParameter.DisplayWidth;
            int presentDisplayHeight = presentParameter.DisplayHeight;
            Bitmap pastBitmap = pastParameter.Bitmap;
            string pastName = pastParameter.Name;
            string pastGroup = pastParameter.Group;
            int pastStartX = pastParameter.StartX;
            int pastStartY = pastParameter.StartY;
            int pastDisplayWidth = pastParameter.DisplayWidth;
            int pastDisplayHeight = pastParameter.DisplayHeight;

            //使用BufferedGraphics作为二次缓冲区
            Graphics bufferGraphics = _bufferedGraphics.Graphics;

            //随机选择图像展开方向，即水平或垂直。以及由内向外或由外向内。
            int presentOrientation = 0;
            int presentDirection = 0;
            int presentSeparator = 0;
            int presentDistance = 0;
            int presentFrameDistance = 0;
            int pastOrientation = 0;
            int pastDirection = 0;
            int pastSeparator = 0;
            int pastDistance = 0;
            int pastFrameDistance = 0;
            Random random = new Random();

            presentOrientation = random.Next(2);
            presentDirection = random.Next(2);
            switch (presentOrientation)
            {
                case 0:
                    presentSeparator = random.Next(presentDisplayWidth);
                    presentDistance = Math.Max(presentSeparator, presentDisplayWidth - 1 - presentSeparator);
                    break;

                case 1:
                    presentSeparator = random.Next(presentDisplayHeight);
                    presentDistance = Math.Max(presentSeparator, presentDisplayHeight - 1 - presentSeparator);
                    break;

                default: break;
            }
            presentFrameDistance = presentDistance / _imageFrameCount;
            if (presentDistance % _imageFrameCount != 0)
                presentFrameDistance++;

            if (pastBitmap != null)
            {
                pastOrientation = random.Next(2);
                pastDirection = random.Next(2);
                switch (pastOrientation)
                {
                    case 0:
                        pastSeparator = random.Next(pastDisplayWidth);
                        pastDistance = Math.Max(pastSeparator, pastDisplayWidth - 1 - pastSeparator);
                        break;

                    case 1:
                        pastSeparator = random.Next(pastDisplayHeight);
                        pastDistance = Math.Max(pastSeparator, pastDisplayHeight - 1 - pastSeparator);
                        break;

                    default: break;
                }
                pastFrameDistance = pastDistance / _imageFrameCount;
                if (pastDistance % _imageFrameCount != 0)
                    pastFrameDistance++;
            }

            CheckThreadBeforePainting();
            for (int i = 0; i < _imageFrameCount; i++)
            {
                if (_cancellationRequested)
                    break;

                bufferGraphics.Clear(_backColor);

                if (pastBitmap != null)
                {
                    if (pastOrientation == 0)
                    {
                        if (pastDirection == 0)
                        {
                            if (i < _imageFrameCount - 1)
                            {
                                int partStartX = pastSeparator - (pastFrameDistance * (_imageFrameCount - i - 1));
                                if (partStartX < 0)
                                    partStartX = 0;
                                int partEndX = pastSeparator + (pastFrameDistance * (_imageFrameCount - i - 1));
                                if (partEndX > pastDisplayWidth - 1)
                                    partEndX = pastDisplayWidth - 1;
                                bufferGraphics.DrawImage(pastBitmap
                                    , new Rectangle(partStartX + pastStartX, pastStartY, partEndX - partStartX + 1, pastDisplayHeight)
                                    , partStartX, 0, partEndX - partStartX + 1, pastDisplayHeight, GraphicsUnit.Pixel);
                            }
                        }
                        else
                        {
                            int partLeftEndX = pastSeparator - (pastFrameDistance * (i + 1));
                            if (partLeftEndX >= 0)
                                bufferGraphics.DrawImage(pastBitmap
                                    , new Rectangle(pastStartX, pastStartY, partLeftEndX + 1, pastDisplayHeight)
                                    , 0, 0, partLeftEndX + 1, pastDisplayHeight, GraphicsUnit.Pixel);
                            int partRightStartX = pastSeparator + (pastFrameDistance * (i + 1));
                            if (partRightStartX < pastDisplayWidth)
                                bufferGraphics.DrawImage(pastBitmap
                                    , new Rectangle(partRightStartX + pastStartX, pastStartY, pastDisplayWidth - partRightStartX, pastDisplayHeight)
                                    , partRightStartX, 0, pastDisplayWidth - partRightStartX, pastDisplayHeight, GraphicsUnit.Pixel);
                        }
                    }
                    else
                    {
                        if (pastDirection == 0)
                        {
                            if (i < _imageFrameCount - 1)
                            {
                                int partStartY = pastSeparator - (pastFrameDistance * (_imageFrameCount - i - 1));
                                if (partStartY < 0)
                                    partStartY = 0;
                                int partEndY = pastSeparator + (pastFrameDistance * (_imageFrameCount - i - 1));
                                if (partEndY > pastDisplayHeight - 1)
                                    partEndY = pastDisplayHeight - 1;
                                bufferGraphics.DrawImage(pastBitmap
                                    , new Rectangle(pastStartX, partStartY + pastStartY, pastDisplayWidth, partEndY - partStartY + 1)
                                    , 0, partStartY, pastDisplayWidth, partEndY - partStartY + 1, GraphicsUnit.Pixel);
                            }
                        }
                        else
                        {
                            int partUpEndY = pastSeparator - (pastFrameDistance * (i + 1));
                            if (partUpEndY >= 0)
                                bufferGraphics.DrawImage(pastBitmap
                                    , new Rectangle(pastStartX, pastStartY, pastDisplayWidth, partUpEndY + 1)
                                    , 0, 0, pastDisplayWidth, partUpEndY + 1, GraphicsUnit.Pixel);
                            int partDownStartY = pastSeparator + (pastFrameDistance * (i + 1));
                            if (partDownStartY < pastDisplayHeight)
                                bufferGraphics.DrawImage(pastBitmap
                                    , new Rectangle(pastStartX, partDownStartY + pastStartY, pastDisplayWidth, pastDisplayHeight - partDownStartY)
                                    , 0, partDownStartY, pastDisplayWidth, pastDisplayHeight - partDownStartY, GraphicsUnit.Pixel);
                        }
                    }
                }

                if (presentOrientation == 0)
                {
                    if (presentDirection == 0)
                    {
                        if (i < _imageFrameCount - 1)
                        {
                            int partStartX = presentSeparator - (presentFrameDistance * (i + 1));
                            if (partStartX < 0)
                                partStartX = 0;
                            int partEndX = presentSeparator + (presentFrameDistance * (i + 1));
                            if (partEndX > presentDisplayWidth - 1)
                                partEndX = presentDisplayWidth - 1;
                            bufferGraphics.DrawImage(presentBitmap
                                , new Rectangle(partStartX + presentStartX, presentStartY, partEndX - partStartX + 1, presentDisplayHeight)
                                , partStartX, 0, partEndX - partStartX + 1, presentDisplayHeight, GraphicsUnit.Pixel);
                        }
                        else
                            bufferGraphics.DrawImageUnscaled(presentBitmap, presentStartX, presentStartY, presentDisplayWidth, presentDisplayHeight);
                    }
                    else
                    {
                        int partLeftEndX = presentSeparator - (presentFrameDistance * (_imageFrameCount - i - 1));
                        if (partLeftEndX >= 0)
                            bufferGraphics.DrawImage(presentBitmap
                                , new Rectangle(presentStartX, presentStartY, partLeftEndX + 1, presentDisplayHeight)
                                , 0, 0, partLeftEndX + 1, presentDisplayHeight, GraphicsUnit.Pixel);
                        int partRightStartX = presentSeparator + (presentFrameDistance * (_imageFrameCount - i - 1));
                        if (partRightStartX < presentDisplayWidth)
                            bufferGraphics.DrawImage(presentBitmap
                                , new Rectangle(partRightStartX + presentStartX, presentStartY, presentDisplayWidth - partRightStartX, presentDisplayHeight)
                                , partRightStartX, 0, presentDisplayWidth - partRightStartX, presentDisplayHeight, GraphicsUnit.Pixel);
                    }
                }
                else
                {
                    if (presentDirection == 0)
                    {
                        if (i < _imageFrameCount - 1)
                        {
                            int partStartY = presentSeparator - (presentFrameDistance * (i + 1));
                            if (partStartY < 0)
                                partStartY = 0;
                            int partEndY = presentSeparator + (presentFrameDistance * (i + 1));
                            if (partEndY > presentDisplayHeight - 1)
                                partEndY = presentDisplayHeight - 1;
                            bufferGraphics.DrawImage(presentBitmap
                                , new Rectangle(presentStartX, partStartY + presentStartY, presentDisplayWidth, partEndY - partStartY + 1)
                                , 0, partStartY, presentDisplayWidth, partEndY - partStartY + 1, GraphicsUnit.Pixel);
                        }
                        else
                            bufferGraphics.DrawImageUnscaled(presentBitmap, presentStartX, presentStartY, presentDisplayWidth, presentDisplayHeight);
                    }
                    else
                    {
                        int partUpEndY = presentSeparator - (presentFrameDistance * (_imageFrameCount - i - 1));
                        if (partUpEndY >= 0)
                            bufferGraphics.DrawImage(presentBitmap
                                , new Rectangle(presentStartX, presentStartY, presentDisplayWidth, partUpEndY + 1)
                                , 0, 0, presentDisplayWidth, partUpEndY + 1, GraphicsUnit.Pixel);
                        int partDownStartY = presentSeparator + (presentFrameDistance * (_imageFrameCount - i - 1));
                        if (partDownStartY < presentDisplayHeight)
                            bufferGraphics.DrawImage(presentBitmap
                                , new Rectangle(presentStartX, partDownStartY + presentStartY, presentDisplayWidth, presentDisplayHeight - partDownStartY)
                                , 0, partDownStartY, presentDisplayWidth, presentDisplayHeight - partDownStartY, GraphicsUnit.Pixel);
                    }
                }

                DrawFileInformation(bufferGraphics, presentName, presentGroup);

                SuspendThreadAfterPainted();
                _bufferedGraphics.Render(Graphics.FromHwnd(_formHandle));
            }
        }
    }
}
